﻿using Contact.API.Data.Core;
using Contact.API.Data.Interface;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace Contact.API.Data
{
    public class MongoContactApplyRequestRepository
        : IContactApplyRequestRepository
    {
        private readonly ContactContext _contactContext;
        public MongoContactApplyRequestRepository(ContactContext contactContext)
        {
            _contactContext = contactContext;
        }
        public async Task<bool> AddRequestAsync(ContactApplyRequest contactApplyRequest, CancellationToken cancellactionToken)
        {
            var filterDefinition = Builders<ContactApplyRequest>.Filter.And(Builders<ContactApplyRequest>.Filter.Eq(c => c.UserId, contactApplyRequest.UserId),
                Builders<ContactApplyRequest>.Filter.Eq(c => c.ApplierId, contactApplyRequest.ApplierId));
            var list = (await _contactContext.ContactApplyRequests.FindAsync(filterDefinition, null, cancellactionToken)).ToList();
            if (list.Any())
            {
                var updateDefinition = Builders<ContactApplyRequest>.Update.Set(c => c.CreateTime, DateTime.Now);
                var result = await _contactContext.ContactApplyRequests.UpdateOneAsync(filterDefinition, updateDefinition, null, cancellactionToken);
                return result.MatchedCount == result.ModifiedCount && result.ModifiedCount == 1;
            }
            await _contactContext.ContactApplyRequests.InsertOneAsync(contactApplyRequest, null, cancellactionToken);
            return true;
        }

        public async Task<bool> ApproveRequestAsync(int applierId, int userId, CancellationToken cancellactionToken)
        {
            var filterDefinition = Builders<ContactApplyRequest>.Filter.And(Builders<ContactApplyRequest>.Filter.Eq(c => c.UserId, userId),
              Builders<ContactApplyRequest>.Filter.Eq(c => c.ApplierId, applierId));
            var list = (await _contactContext.ContactApplyRequests.FindAsync(filterDefinition, null, cancellactionToken)).ToList();
            if (!list.Any())
            {
                throw new Exception($"user id not exist for userId {userId}");
            }
            var updateDefinition = Builders<ContactApplyRequest>.Update.Set(c => c.HandleTime, DateTime.Now).Set(c=>c.Approved,true);
            var result = await _contactContext.ContactApplyRequests.UpdateOneAsync(filterDefinition, updateDefinition, null, cancellactionToken);

            //tbd:insert ContactApplyRequest
            //_contactContext.ContactApplyRequests.InsertOneAsync()
            return true;
        }

        public async Task<List<ContactApplyRequest>> GetContactRequestListAsync(int userId, CancellationToken cancellactionToken)
        {
            var filterDefinition = Builders<ContactApplyRequest>.Filter.Eq(c => c.UserId, userId);
            var list = (await _contactContext.ContactApplyRequests.FindAsync(filterDefinition, null, cancellactionToken)).ToList();
            return list;
        }
    }
}
